// imports necessary for openGL
import processing.opengl.*;
import javax.media.opengl.*;

// import necessary for GLGraphics lib
import codeanticode.glgraphics.*;

GLTexture handTex;

class TouchHand
{
  private float posX, posY;
  private float sizeX, sizeY;
  private PVector vecTouch;
  private PVector vecSource, vecCur, vecDest;
  private boolean on;
  
  final int stateOff = 0, stateStarting = 1, stateHoverSource = 2, stateMoving = 3, stateHoverDest = 4, stateStopping = 5, stateWaiting = 6;
  final float moveTime = 1000.0;
  final float waitTime = 1000.0;
  //final float hoverTime = 1000.0;
  final float speedFadeIn = 0.002;
  final float speedFadeOut = 0.002;
  int curState;
  float timer;
  float visibility;
  
  TouchHand()
  {
    on = false;
    curState = stateOff;
    timer = 0.0;
    visibility = 0.0;
    sizeX = handSize;
    sizeY = handSize;
    vecTouch = new PVector(0,0);
    vecSource  = new PVector(0,0);
    vecCur = new PVector(0,0);
    vecDest = new PVector(0,0);
  }
  
  void update(float milliseconds)
  {
    if(curState == stateOff)
    {
      // do nothing
    }
    else if(curState == stateStarting)
    {
      visibility += milliseconds * speedFadeIn;
      if(visibility > 1.0)
      {
        curState = stateHoverSource;
        visibility = 1.0;
        timer = 0.0;
      }
    }
    else if(curState == stateHoverSource)
    {
      // increment hover timer
      timer += milliseconds;
      
      if(timer > handHoverTime * 1000.0)
      {
        // time to initiate the movement of the hand
        curState = stateMoving;
        timer = 0.0;
      }
    }
    else if(curState == stateMoving)
    {
      // increment move timer
      timer += milliseconds;
      
      // update current position
      vecCur.x = vecSource.x + (vecDest.x - vecSource.x) * min(1.0,timer / moveTime);
      vecCur.y = vecSource.y + (vecDest.y - vecSource.y) * min(1.0,timer / moveTime);
      
      vecTouch.x = vecCur.x;
      vecTouch.y = vecCur.y;
      
      if(timer > moveTime)
      {
        // start hovering at dest
        curState = stateHoverDest;
        timer = 0.0;
        
        vecCur.x = vecDest.x;
        vecCur.y = vecDest.y;
      }
    }
    else if(curState == stateHoverDest)
    {
      // increment hover timer
      timer += milliseconds;
      
      if(timer > handHoverTime * 1000.0)
      {
        // time to initiate fading out
        curState = stateStopping;
        timer = 0.0;
      }
    }
    else if(curState == stateStopping)
    {
      visibility -= milliseconds * speedFadeOut;
      if(visibility < 0.0)
      {
        visibility = 0.0;
        
        if(on == true)
        {
          curState = stateWaiting;
          timer = 0.0;
        }
        else
        {
          curState = stateOff;
        }
      }
    }
    else if(curState == stateWaiting)
    {
      timer += milliseconds;
      if(timer > waitTime)
      {
        timer = 0.0;
        move();
      }
    }
  }
  
  void render()
  {
    if(curState != stateOff)
    {
      tint(255,255,255,ceil(min(visibility,1.0) * 140.0));
      
      imageMode(CENTER);
      image(handTex,vecCur.x,vecCur.y,sizeX,sizeY);
      imageMode(CORNER);
    }
  }
  
  PVector getTouch()
  {
    if(curState == stateHoverSource || curState == stateMoving || curState == stateHoverDest)
    {
      
      return vecTouch;
    }
    else
    {
      return null;
    }
  }
  
  void start(float _posX, float _posY)
  {
    if(on == false)
    {
      on = true;
      move();
    }
    /*
    if(curState == stateOff || curState == stateStopping)
    {
      curState = stateStarting;
      timer = 0.0;
      
      posX = _posX;
      posY = _posY;
    }
    */
  }
  
  void stop()
  {
    if(on == true)
    {
      on = false;
      curState = stateStopping;
      timer = 0.0;
    }
  }
  
  boolean isOn()
  {
    return on;
  }
  
  private void move()
  {
    // reposition hand
    vecSource = generateSafeCoord();
    vecDest   = generateSafeCoord();
    
    vecCur.x = vecSource.x;
    vecCur.y = vecSource.y;
    vecTouch.x = vecCur.x;
    vecTouch.y = vecCur.y;
    
    // reposition touch
    //vecTouch.x = posX;
    //vecTouch.y = posY;// - sizeY / 2.0;
    
    timer = 0.0;
    curState = stateStarting;
  }
  
  private PVector generateSafeCoord()
  {
    PVector vec = new PVector();
    vec.x = width * 0.15 + random(width * 0.7);
    vec.y = height * 0.3 + random(height * 0.55);
    return vec;
  }
}


